package com.topscomm.tap.common;

import com.topscomm.basic.IBasicService;
import com.topscomm.cbo.pojo.*;
import com.topscomm.cbo.service.ICboItemsService;
import com.topscomm.mms.pojo.MmsDeptExtraInfoEntity;
import com.topscomm.mms.pojo.MmsProductBaseInfoEntity;
import com.topscomm.mms.pojo.MmsProvinceCityMatchinfoEntity;
import com.topscomm.mms.pojo.MmsSensitiveThesaurusEntity;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.SpringUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.pub.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description TODO
 * @Classname LtcDataCodeCache1
 * @Date 2022/7/13
 * @Created by jiangtao
 */
@Component(value = "ltcDatacodeCache")
@Scope(value = "prototype")
public class LtcDatacodeCache extends DatacodeCache implements Serializable {
	/**
	 * @type: long
	 * @description:
	 */
	private static final long serialVersionUID = 1L;
	/**
	 * 编码明细缓存对象itemDetailCache中，key的默认分隔符
	 */
	private static final String SPLIT_STRING = "_";
	private Map<String, CboItemsEntity> itemCache = new HashMap<String, CboItemsEntity>();
	private Map<String, List<Map<String, Object>>> itemDetailCache = new HashMap<String, List<Map<String, Object>>>();
	@Autowired
	private RedisDatacodeStore redisDatacodeStore;
	@Autowired
	private RedisMmsStore redisMmsStore;
	// 这些表的编码数据，进行强制缓存（若有新增数据，会判断进行强制刷新）
	private static List<String> cacheTableCode = new ArrayList<>();
	static {
		cacheTableCode.add(CboUserEntity.tableName);
		cacheTableCode.add(CboDeptEntity.tableName);
		cacheTableCode.add(CboApprovalNodeEntity.tableName);
		cacheTableCode.add(MmsProvinceCityMatchinfoEntity.tableName);
		cacheTableCode.add(MmsSensitiveThesaurusEntity.tableName);
	}
	// 存储表名和需要查询的字段
	private static Map<String, List<String>> mmsFieldsList = new HashMap<String, List<String>>();
	static {
		mmsFieldsList.put(MmsDeptExtraInfoEntity.tableName, getMmsDeptExtraInfoFields());
		mmsFieldsList.put(MmsProductBaseInfoEntity.tableName, getMmsProductBaseInfoFields());
		mmsFieldsList.put(MmsProvinceCityMatchinfoEntity.tableName, getMmsProvinceCityMatchinfoFields());
		mmsFieldsList.put(MmsSensitiveThesaurusEntity.tableName, getMmsSensitiveThesaurusinfoFields());
	}

	/**
	 * @author: zhangsui
	 * @date: 2016年3月31日上午10:51:38
	 * @param itemCode
	 * @param values
	 * @param inCol
	 * @param outCol
	 * @return
	 * @return_type: String
	 * @description:批量转换显示值
	 * @modify:
	 */
	public String getValueDynamic(String itemCode, String[] values, String inCol, String outCol) {
		if (values == null || values.length <= 0) {
			return "";
		}
		StringBufferProxy resultValue = new StringBufferProxy();
		for (String value : values) {
			String tempValue = getValueDynamic(itemCode, value, inCol, outCol);
			if (!StringUtil.isEmpty(tempValue)) {
				resultValue.appendSingle("{0},", tempValue);
			}
		}
		if (resultValue.length() > 0) {
			resultValue = resultValue.substring(0, resultValue.length() - 1);
		}
		return resultValue.toString();
	}

	/**
	 * @author: zhangsui
	 * @date: 2016年3月31日上午10:51:38
	 * @param itemCode
	 * @param value
	 * @param inCol
	 * @param outCol
	 * @return
	 * @return_type: String
	 * @description:转换显示值
	 * @modify:
	 */
	public String getValueDynamic(String itemCode, String value, String inCol, String outCol) {
		return getValueDynamic(itemCode, "", value, inCol, outCol);
	}

	/**
	 * @description:转换显示值
	 * @param itemCode
	 * @param fieldName
	 * 根据提前调用loadItemDetailCache方法，追加的fieldName进行获取
	 * @param value
	 * @param inCol
	 * @param outCol
	 * @return
	 * @author: zhanglongfei
	 * @date: 2021年10月15日下午2:55:29
	 * @modify:
	 */
	public String getValueDynamic(String itemCode, String fieldName, String value, String inCol, String outCol) {
		if (value == null) {
			return "";
		}
		String fullKey = itemCode;
		if (!StringUtil.isEmpty(fieldName)) {
			fullKey = itemCode + SPLIT_STRING + fieldName;
		}
		// 加载item明细，如果提前没有调用loadItemDetailCache进行缓存，那么还是获取原源码，如果提前缓存了，那么使用组件key进行获取缓存
		List<Map<String, Object>> mapList = null;
		if (!this.itemDetailCache.containsKey(fullKey)) {
			if (this.itemDetailCache.containsKey(itemCode)) {
				mapList = this.itemDetailCache.get(itemCode);
			} else {
				mapList = this.getCodeListMap(itemCode, "", "sortcode");
				this.itemDetailCache.put(itemCode, mapList);
			}
		} else {
			mapList = this.itemDetailCache.get(fullKey);
		}
		if (mapList == null || mapList.size() <= 0) {
			return "";
		}
		// 转换值
		/********************* 并行实现 *********************/
		Optional<Map<String, Object>> resultOptional = mapList.parallelStream()
				.filter(dataMap -> {
					String tempValue = ConvertUtil.convertToString(dataMap.get(inCol));
					return tempValue.equals(value);
				})
				.findFirst();
		if (resultOptional.isPresent()) {
			Map<String, Object> resultDataMap = resultOptional.get();
			if (resultDataMap != null) {
				return ConvertUtil.convertToString(resultDataMap.get(outCol));
			}
		}
		return "";
		/********************* 串行实现 *********************/
		// for (Map<String, Object> dataMap : mapList) {
		// String tempValue = ConvertUtil.convertToString(dataMap.get(inCol));
		// if (tempValue.equals(value)) {
		// return ConvertUtil.convertToString(dataMap.get(outCol));
		// }
		// }
		// return "";
	}

	/**
	 * @author: zhangsui
	 * @date: 2016年3月31日上午10:54:13
	 * @param itemCode
	 * @return
	 * @return_type: List<Map>
	 * @description:通过代码编码获取代码明细集合
	 * @modify:
	 */
	public List<Map<String, Object>> getCodeListMap(String itemCode) {
		return getCodeListMap(itemCode, "");
	}

	/**
	 * @author: zhangsui
	 * @date: 2016年3月31日上午10:53:53
	 * @param ItemCode
	 * @param sqlWhere
	 * @return
	 * @return_type: List<Map>
	 * @description:通过代码编号、Where条件获取代码明细集合
	 * @modify:
	 */
	public List<Map<String, Object>> getCodeListMap(String ItemCode, String sqlWhere) {
		return getCodeListMap(ItemCode, sqlWhere, "");
	}

	/**
	 * @author: zhangsui
	 * @date: 2016年3月31日上午10:54:13
	 * @param itemCode
	 * @param sqlWhere
	 * @param order
	 * @return
	 * @return_type: List<Map>
	 * @description:通过代码编号、Where条件、Order条件来获取代码明细集合
	 * @modify:
	 */
	public List<Map<String, Object>> getCodeListMap(String itemCode, String sqlWhere, String order) {
		List<Map<String, Object>> mapList = redisDatacodeStore.queryData(itemCode);
		if (mapList != null) {
			return mapList;
		}
		// 查询item对象
		CboItemsEntity item = this.getItemEntity(itemCode);
		if (item == null) {
			return new ArrayList<Map<String, Object>>();
		}
		// 获取service对象
		IBasicService<?, ?> service = this.getServiceInstance(item);
		// 查询item明细
		StringBufferProxy sql = new StringBufferProxy();
		if (item.getTargettable().equals(CboItemDetailsEntity.tableName)) {
			sql.appendLineSingle(" itemid = '{0}'", item.getId());
		} else {
			sql.appendLineSingle(" 1=1 ");
		}
		if (!StringUtil.isEmpty(item.getTargetcondition())) {
			sql.appendSingle(" and {0} ", item.getTargetcondition());
		}
		if (!StringUtil.isEmpty(sqlWhere.trim())) {
			sql.appendSingle(" and {0} ", sqlWhere);
		}
		if (!StringUtil.isEmpty(order)) {
			sql.appendSingle(" order by {0} ", order);
		}
		List<String> filedList = new ArrayList<String>();
		filedList.add(item.getIdcol() + " as id");
		filedList.add(item.getCodecol() + " as code");
		filedList.add(item.getNamecol() + " as name");
		filedList.add(item.getEnabled() + " as enabled");
		mapList = service.queryMapFieldsByWhere(sql.toString(), filedList);
		if (CboItemDetailsEntity.tableName.equals(item.getTargettable())) {
			redisDatacodeStore.storeData(itemCode, mapList);
		} else if (cacheTableCode.contains(item.getTargettable())) {
			redisDatacodeStore.storeData(itemCode, mapList);
		}
		return mapList;
	}

	/**
	 * @description:加载编码明细，并将编码明细保存到itemDetailCache中
	 * @param itemCode
	 * 要缓存的CboItemCode
	 * @param itemCol
	 * 转换值中对应的CobItem表的列
	 * @param mapKey
	 * 业务表中的字段
	 * @param mapRowList
	 * 业务表数据
	 * @return
	 * @author: zhanglongfei
	 * @date: 2021年10月15日下午2:40:18
	 * @modify:
	 */
	public List<Map<String, Object>> loadItemDetailCache(String itemCode, String itemCol, String mapKey, List<Map<String, Object>> mapRowList) {
		if (mapRowList == null || mapRowList.isEmpty()) {
			return new ArrayList<Map<String, Object>>();
		}
		CboItemsEntity itemEntity = this.getItemEntity(itemCode);
		if (itemEntity == null) {
			return new ArrayList<Map<String, Object>>();
		}
		List<String> keys = mapRowList.stream().map(item -> ConvertUtil.convertToString(item.get(mapKey))).distinct().collect(Collectors.toList());
		if (keys == null) {
			return new ArrayList<Map<String, Object>>();
		}
		keys.removeIf(item -> StringUtil.isEmpty(item));
		if (!keys.isEmpty()) {
			StringBufferProxy sql = new StringBufferProxy();
			sql.appendSingle(" {0} in (", itemEntity.getValue(itemCol + "col"));
			keys.stream().forEach(item -> {
				sql.appendSingle("'{0}', ", ConvertUtil.convertToString(item));
			});
			// 后面的一个空格和一个逗号
			StringBufferProxy whereSql = sql.substring(0, sql.length() - 2);
			whereSql.appendSingle(")");
			return loadItemDetailCache(itemCode, mapKey, "");
		} else {
			return new ArrayList<Map<String, Object>>();
		}
	}

	/**
	 * @description:加载编码明细，并将编码明细保存到itemDetailCache中
	 * @param ItemCode
	 * @return
	 * @author: zhanglongfei
	 * @date: 2021年10月15日下午2:06:04
	 * @modify:
	 */
	public List<Map<String, Object>> loadItemDetailCache(String ItemCode) {
		return loadItemDetailCache(ItemCode, "");
	}

	/**
	 * @description:加载编码明细，并将编码明细保存到itemDetailCache中
	 * @param ItemCode
	 * @param sqlWhere
	 * @return
	 * @author: zhanglongfei
	 * @date: 2021年10月15日下午2:06:57
	 * @modify:
	 */
	public List<Map<String, Object>> loadItemDetailCache(String ItemCode, String sqlWhere) {
		return loadItemDetailCache(ItemCode, "", sqlWhere);
	}

	/**
	 * @description:加载编码明细，并将编码明细保存到itemDetailCache中
	 * @param ItemCode
	 * @param fieldName
	 * @param sqlWhere
	 * @return
	 * @author: zhanglongfei
	 * @date: 2021年10月15日下午2:07:08
	 * @modify:
	 */
	public List<Map<String, Object>> loadItemDetailCache(String ItemCode, String fieldName, String sqlWhere) {
		return loadItemDetailCache(ItemCode, fieldName, sqlWhere, "");
	}

	/**
	 * @description: 加载编码明细，并将编码明细保存到itemDetailCache中
	 * @param itemCode
	 * CboItem表的code
	 * @param fieldName
	 * 缓存时，要追加的key后缀
	 * @param sqlWhere
	 * @param order
	 * @return
	 * @author: zhanglongfei
	 * @date: 2021年10月15日下午11:45:34
	 * @modify:
	 */
	public List<Map<String, Object>> loadItemDetailCache(String itemCode, String fieldName, String sqlWhere, String order) {
		List<Map<String, Object>> list = getCodeListMap(itemCode, sqlWhere, order);
		String fullKey = itemCode;
		if (!StringUtil.isEmpty(fieldName)) {
			fullKey = itemCode + SPLIT_STRING + fieldName;
		}
		itemDetailCache.put(fullKey, list);
		return list;
	}

	/**
	 * @author: zhangsui
	 * @date: 2018年1月23日下午6:10:11
	 * @description:清理缓存
	 * @modify:
	 */
	public static void clearCache() {
	}

	/**
	 * @author: zhangsui
	 * @date: 2018年1月25日下午5:47:01
	 * @description:代码对象
	 * @modify:
	 */
	protected CboItemsEntity getItemEntity(String itemCode) {
		if (!this.itemCache.containsKey(itemCode)) {
			StringBufferProxy sql = new StringBufferProxy();
			sql.appendLineSingle(" code='{0}' ", itemCode);
			ICboItemsService cboItemsService = (ICboItemsService) getServiceInstance("cboItemsService");
			CboItemsEntity item = cboItemsService.queryObjectByWhere(sql.toString());
			if (item != null) {
				this.itemCache.put(itemCode, item);
			}
		}
		return this.itemCache.get(itemCode);
	}

	/**
	 * @author: zhangsui
	 * @date: 2018年1月24日下午6:18:10
	 * @description: 创建服务实例
	 * @modify:
	 */
	private IBasicService<?, ?> getServiceInstance(CboItemsEntity item) {
		String serviceName = item.getTargettable() + "Service";
		serviceName = StringUtil.lowerFirst(serviceName);
		return getServiceInstance(serviceName);
	}

	/**
	 * @author: zhangsui
	 * @date: 2018年1月24日下午6:18:10
	 * @description: 创建服务实例
	 * @modify:
	 */
	private IBasicService<?, ?> getServiceInstance(String serviceName) {
		IBasicService<?, ?> service = (IBasicService<?, ?>) SpringUtil.getBean(serviceName);
		return service;
	}
	/**
	 *
	 * @description:获取敏感词信息中需要存储到redis的字段
	 * @return
	 * @author: hdy
	 * @date: 2021年6月16日下午3:47:42
	 * @modify:
	 */
	protected static List<String> getMmsSensitiveThesaurusinfoFields() {
		List<String> filedList = new ArrayList<String>();
		filedList.add(MmsSensitiveThesaurusEntity.FieldId);
		filedList.add(MmsSensitiveThesaurusEntity.FieldType);
		filedList.add(MmsSensitiveThesaurusEntity.FieldWord);
		filedList.add(MmsSensitiveThesaurusEntity.FieldRangesys);
		return filedList;
	}

	/**
	 *
	 * @description:获取部门扩展信息中需要存储到redis的字段
	 * @return
	 * @author: jiangtao1
	 * @date: 2021年6月16日下午3:47:42
	 * @modify:
	 */
	protected static List<String> getMmsDeptExtraInfoFields() {
		List<String> filedList = new ArrayList<String>();
		filedList.add(MmsDeptExtraInfoEntity.FieldId);
		filedList.add(MmsDeptExtraInfoEntity.FieldDeptcode);
		filedList.add(MmsDeptExtraInfoEntity.FieldDeptcommoncode);
		filedList.add(MmsDeptExtraInfoEntity.FieldDeptname);
		filedList.add(MmsDeptExtraInfoEntity.FieldDeptcommonmark);
		filedList.add(MmsDeptExtraInfoEntity.FieldProvincemanagercode);
		filedList.add(MmsDeptExtraInfoEntity.FieldProvincemanagername);
		filedList.add(MmsDeptExtraInfoEntity.FieldCfocode);
		filedList.add(MmsDeptExtraInfoEntity.FieldCfoname);
		return filedList;
	}


	/**
	 *
	 * @description:获取产品信息中需要存储到redis的字段
	 * @return
	 * @author: jiangtao1
	 * @date: 2021年6月16日下午4:12:44
	 * @modify:
	 */
	protected static List<String> getMmsProductBaseInfoFields() {
		List<String> filedList = new ArrayList<String>();
		filedList.add(MmsProductBaseInfoEntity.FieldId);
		filedList.add(MmsProductBaseInfoEntity.FieldName);
		filedList.add(MmsProductBaseInfoEntity.FieldProductline);
		filedList.add(MmsProductBaseInfoEntity.FieldDeptcodearray);
		filedList.add(MmsProductBaseInfoEntity.FieldDeptcodearrayname);
		filedList.add(MmsProductBaseInfoEntity.FieldCatalog1);
		filedList.add(MmsProductBaseInfoEntity.FieldCatalog2);
		filedList.add(MmsProductBaseInfoEntity.FieldMarketingclassification);
		return filedList;
	}

	/**
	 *
	 * @description:获取省市地区信息中需要存储到redis的字段
	 * @return
	 * @author: jiangtao1
	 * @date: 2021年6月16日下午4:18:56
	 * @modify:
	 */
	protected static List<String> getMmsProvinceCityMatchinfoFields() {
		List<String> filedList = new ArrayList<String>();
		filedList.add(MmsProvinceCityMatchinfoEntity.FieldId);
		filedList.add(MmsProvinceCityMatchinfoEntity.FieldDeptcommoncode);
		filedList.add(MmsProvinceCityMatchinfoEntity.FieldName);
		filedList.add(MmsProvinceCityMatchinfoEntity.FieldArealevel);
		filedList.add(MmsProvinceCityMatchinfoEntity.FieldCode);
		filedList.add(MmsProvinceCityMatchinfoEntity.FieldLevelcode);
		filedList.add(MmsProvinceCityMatchinfoEntity.FieldAreaauthorizationusercode);
		filedList.add(MmsProvinceCityMatchinfoEntity.FieldAreaauthorizationusername);
		filedList.add(MmsProvinceCityMatchinfoEntity.FieldParentid);
		filedList.add(MmsProvinceCityMatchinfoEntity.FieldRealarea);
		filedList.add(MmsProvinceCityMatchinfoEntity.FieldAreamatch);
		return filedList;
	}
}
